/*******************************************************************************
 * Copyright (c) 2002 Boris Pruessmann and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Common Public License v0.5
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors:
 *    Boris Pruessmann - Initial implementation.
 ******************************************************************************/
package net.sourceforge.perforce.ui.dialogs;

import net.sourceforge.perforce.core.api.ResolveTypeEnum;
import net.sourceforge.perforce.ui.IPerforceUIConstants;
import net.sourceforge.perforce.ui.PerforceUIPlugin;
import net.sourceforge.perforce.ui.internal.Policy;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.swt.events.HelpEvent;
import org.eclipse.swt.events.HelpListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.help.WorkbenchHelp;

/**
  * @version $Revision: 202 $
  * @author  <a href="mailto:bpruessmann@users.sourceforge.net">Boris Pruessmann</a>
  */
public class AutoResolveDialog extends Dialog 
{
	// --------------------------------------------------------------------------- Private Variables
	
	/** Combo: Resolve Type */
	private Combo resolveTypeCombo;
	/** Button: Re-resolve previously resolved but unsubmitted files */
	private Button reResolveButton;
	/** Button: Attempt textual merge of bianry files */
	private Button attemptBinaryMergeButton; 
	
	/** Indicates whether re-resolve is available or not. */
	private boolean enableReResolve;
	
	/** Stores the current selection. */
	private ResolveTypeEnum currentResolveType;
	/** Stores the current check state of the reResolveButton */
	private boolean currentReResolve;
	/** Stores the current check state of the attemptBinaryMergeButton */
	private boolean currentAttemptBinaryMerge;	
	
	// ------------------------------------------------------------------------- Public Constructors
	
	/** Constructor for AutoResolveDialog.
	  *
	  * @param parent the parent shell.
	  * @param reResolveEnabled indicates whether the reResolveButton should be enabled or not.
	  */
	public AutoResolveDialog(Shell parent, boolean reResolveEnabled)
	{
		super(parent);
		enableReResolve = reResolveEnabled;
	}
	
	// ------------------------------------------------------------------------------ Public Methods
	
	/** Called to retrieve the resolve type that was selectd.
	  *
	  * @return THEIRS, YOURS, SAFE_AUTOMATIC, AUTOMATIC or AUTOMATIC_MARKERS. 
	  */
	public ResolveTypeEnum getResolveType()
	{
		return currentResolveType;
	}
	
	/** Called to check whether the user wants to re-resolve previously resolved files.
	  *
	  * @return true or false. 
	  */
	public boolean shouldReResolve()
	{
		return enableReResolve ? currentReResolve : false;
	}
	
	/** Indicates whether the user wants to perform a textual merge of binary files.
	  *
	  * @return true or false. 
	  */
	public boolean shouldAttemptBinaryMerge()
	{
		return currentAttemptBinaryMerge;
	}
	
	/** @see Window#create() */
	public void create()
	{
		super.create();
		readSettings();
	}

	/** @see Dialog#close() */
	public boolean close()
	{
		if (getReturnCode() == OK)
		{
			writeSettings();
		}
		
		return super.close();		
	}
	
	// --------------------------------------------------------------------------- Protected Methods
	
	/** @see Dialog#configureShell(Shell) */
	protected void configureShell(Shell newShell) 
	{
		super.configureShell(newShell);
		newShell.setText(Policy.bind("AutoResolveDialog.title")); //$NON-NLS-1$
	}
	
	/** @see Dialog#createDialogArea(Composite) */
	protected Control createDialogArea(Composite parent)
	{
		Composite composite = DialogUtils.createComposite(parent, 2);
		
		DialogUtils.createLabel(
			composite, 
			Policy.bind("AutoResolveDialog.ResolveType"));                             //$NON-NLS-1$
			
		resolveTypeCombo = DialogUtils.createCombo(
			composite, 
			convertVerticalDLUsToPixels(140));
		fileResolveTypeCombo(resolveTypeCombo);
		
		resolveTypeCombo.setFocus();
		resolveTypeCombo.addHelpListener(new HelpListener()
		{
			public void helpRequested(HelpEvent event)
			{
				ResolveTypeEnum resolveType = 
					ResolveTypeEnum.fromId(resolveTypeCombo.getSelectionIndex());
				if (resolveType == ResolveTypeEnum.ACCEPT_THEIRS)
				{
						WorkbenchHelp.displayHelp(IPerforceUIConstants.AUTO_RESOLVE_TYPE_THEIRS);
				}
				else
				if (resolveType == ResolveTypeEnum.ACCEPT_YOURS)
				{
						WorkbenchHelp.displayHelp(IPerforceUIConstants.AUTO_RESOLVE_TYPE_YOURS);
				}
				else
				if (resolveType == ResolveTypeEnum.SAFE_AUTOMATIC)
				{
						WorkbenchHelp.displayHelp(
							IPerforceUIConstants.AUTO_RESOLVE_TYPE_SAFE_AUTOMATIC);
				}
				else
				if (resolveType == ResolveTypeEnum.AUTOMATIC)
				{
						WorkbenchHelp.displayHelp(IPerforceUIConstants.AUTO_RESOLVE_TYPE_AUTOMATIC);
				}
				else
				if (resolveType == ResolveTypeEnum.AUTOMATIC_MARKERS)
				{
						WorkbenchHelp.displayHelp(
							IPerforceUIConstants.AUTO_RESOLVE_TYPE_AUTOMATIC_MARKERS);
				}
			}
		});
		resolveTypeCombo.addSelectionListener(new SelectionAdapter()
		{
			public void widgetSelected(SelectionEvent event)
			{
				currentResolveType = ResolveTypeEnum.fromId(resolveTypeCombo.getSelectionIndex());
			}
		});
		
		// Re-Resolve button
		String buttonText = Policy.bind(
			"AutoResolveDialog.Re-resolve_previously_resolved_but_unsubmitted_files"); //$NON-NLS-1$
		reResolveButton = DialogUtils.createCheckButton(composite, buttonText);
		reResolveButton.setEnabled(enableReResolve);
		
		GridData data = new GridData();
		data.horizontalSpan = 2;
		reResolveButton.setLayoutData(data);
		
		reResolveButton.addSelectionListener(new SelectionAdapter()
		{			
			public void widgetSelected(SelectionEvent arg0)
			{
				currentReResolve = reResolveButton.getSelection();
			}
		});
				
		// Attempt binary merge button
		buttonText = 
			Policy.bind("AutoResolveDialog.Attempt_textual_merge_of_bianry_files");    //$NON-NLS-1$
		attemptBinaryMergeButton = DialogUtils.createCheckButton(composite, buttonText);
				
		data = new GridData();
		data.horizontalSpan = 2;		
		attemptBinaryMergeButton.setLayoutData(data);
		
		attemptBinaryMergeButton.addSelectionListener(new SelectionAdapter()
		{			
			public void widgetSelected(SelectionEvent arg0)
			{
				currentAttemptBinaryMerge = attemptBinaryMergeButton.getSelection();
			}
		});
				
		return composite;
	}

	// ----------------------------------------------------------------------------- Private Methods
	
	/** Returns <code>true</code> if control can be used
	  *
	  * @param control the control to be checked
	  * @return <code>true</code> if control can be used
	  */
	private boolean okToUse(Control control) 
	{
		return control != null && !control.isDisposed();
	}

	/** Retrieves the associated IDialogSettings.
	  *
	  * @return the dialog settings. 
	  */
	private IDialogSettings getDialogSettings()
	{
		IDialogSettings pluginSettings = PerforceUIPlugin.getPlugin().getDialogSettings();
		IDialogSettings dialogSettings = pluginSettings.getSection(getClass().getName());
		
		if (dialogSettings == null)
		{
			dialogSettings = pluginSettings.addNewSection(getClass().getName());
		}
			
		return dialogSettings;
	}
	
	/** Reads the dialogs settings. */ 
	private void readSettings()
	{
		IDialogSettings settings = getDialogSettings();
		
		try
		{
			currentResolveType = 
				ResolveTypeEnum.fromId(settings.getInt("resolveType"));                //$NON-NLS-1$
		}
		catch (NumberFormatException e)
		{	
			currentResolveType = ResolveTypeEnum.ACCEPT_THEIRS; 		
		}
		finally
		{
			resolveTypeCombo.select(currentResolveType.getId());
		}		
		
		currentReResolve = settings.getBoolean("reResolve");                           //$NON-NLS-1$
		reResolveButton.setSelection(currentReResolve);
		
		currentAttemptBinaryMerge = settings.getBoolean("attemptBinaryMerge");         //$NON-NLS-1$
		attemptBinaryMergeButton.setSelection(currentAttemptBinaryMerge);
	}
	
	/** Writes the dialogs settings. */
	private void writeSettings()
	{
		IDialogSettings settings = getDialogSettings();
		
		settings.put("resolveType", currentResolveType.getId());                       //$NON-NLS-1$
		settings.put("reResolve", currentReResolve);                                   //$NON-NLS-1$
		settings.put("attemptBinaryMerge", currentAttemptBinaryMerge);                 //$NON-NLS-1$
	}
	
	// ---------------------------------------------------------------------- Private Static Methods
	
	/** Fills the given combo with the available resolve types.
	  * 
	  * @param combo the combo to fill.
	  */
	private static void fileResolveTypeCombo(Combo combo)
	{
		combo.add(Policy.bind("AutoResolveDialog.Accept_theirs"));                     //$NON-NLS-1$
		combo.add(Policy.bind("AutoResolveDialog.Accept_yours"));                      //$NON-NLS-1$
		combo.add(Policy.bind("AutoResolveDialog.Safe_automatic_resolve"));            //$NON-NLS-1$
		combo.add(Policy.bind("AutoResolveDialog.Automatic_resolve"));                 //$NON-NLS-1$
		combo.add(
			Policy.bind(
				"AutoResolveDialog.Automatic_resolve,_including_conflict_markers_9")); //$NON-NLS-1$
	}
}
